/*
 * @Author: jianfanfan 1217572833@qq.com
 * @Date: 2025-04-01 11:30:00
 * @LastEditors: jianfanfan 1217572833@qq.com
 * @LastEditTime: 2025-04-01 19:24:43
 * @FilePath: \guozaoke\src\common\services\cache.service.ts
 * @Description: Redis缓存服务
 */
import { Injectable, Inject } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';

@Injectable()
export class CacheService {
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  /**
   * 获取缓存数据
   * @param key 缓存键
   * @returns 缓存数据
   */
  async get<T>(key: string): Promise<T | undefined> {
    const value = await this.cacheManager.get<T>(key);
    return value === null ? undefined : value;
  }

  /**
   * 设置缓存数据
   * @param key 缓存键
   * @param value 缓存值
   * @param ttl 过期时间(秒)，默认1小时
   */
  async set(key: string, value: any, ttl: number = 3600): Promise<void> {
    await this.cacheManager.set(key, value, ttl);
  }

  /**
   * 删除缓存数据
   * @param key 缓存键
   */
  async del(key: string): Promise<void> {
    await this.cacheManager.del(key);
  }

  /**
   * 清除所有缓存
   */
  async reset(): Promise<void> {
    // cache-manager v6 不再支持reset方法，使用del方法清除特定键
    // 如需清除所有缓存，需要单独删除每个键
    // 这里提供一个简单实现，实际使用时可能需要更复杂的逻辑
    // 如果有需要，可以考虑使用Redis客户端的flushall命令
    console.log(
      'Cache reset method called, but not fully implemented in cache-manager v6',
    );
  }

  /**
   * 获取缓存数据，如果不存在则通过回调函数获取并缓存
   * @param key 缓存键
   * @param callback 回调函数，用于获取数据
   * @param ttl 过期时间(秒)，默认1小时
   * @returns 缓存数据
   */
  async getOrSet<T>(
    key: string,
    callback: () => Promise<T>,
    ttl: number = 3600,
  ): Promise<T> {
    const cachedData = await this.get<T>(key);
    if (cachedData) {
      return cachedData;
    }

    const freshData = await callback();
    await this.set(key, freshData, ttl);
    return freshData;
  }
}
